package com.chucang.shucang.oms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.chucang.shucang.common.base.constant.SecurityConstant;
import com.chucang.shucang.common.base.exception.FastException;
import com.chucang.shucang.common.base.redis.RedisUtil;
import com.chucang.shucang.common.base.redis.vo.PanicPurchaseProductRedisVO;
import com.chucang.shucang.common.base.service.impl.CrudServiceImpl;
import com.chucang.shucang.common.base.utils.OpsUtil;
import com.chucang.shucang.common.base.utils.R;
import com.chucang.shucang.common.mq.constant.RabbitConstant;
import com.chucang.shucang.common.mq.to.ClosePayInfoTO;
import com.chucang.shucang.oms.constant.OmsCacheConstant;
import com.chucang.shucang.oms.constant.OmsCommonConstant;
import com.chucang.shucang.oms.dao.BlindBoxOrderBaseDao;
import com.chucang.shucang.oms.dto.BlindBoxOrderBaseDTO;
import com.chucang.shucang.oms.entity.BlindBoxOrderBaseEntity;
import com.chucang.shucang.oms.feign.PmsService;
import com.chucang.shucang.oms.feign.vo.BlindBoxBaseEntity;
import com.chucang.shucang.oms.service.BlindBoxOrderBaseService;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;


/**
 * 盲盒基础订单表
 *
 * @author flitsneak flitsneak@gmail.com
 * @since 1.0.0 2022-09-12
 */
@Service
@RequiredArgsConstructor
public class BlindBoxOrderBaseServiceImpl extends CrudServiceImpl<BlindBoxOrderBaseDao, BlindBoxOrderBaseEntity, BlindBoxOrderBaseDTO> implements BlindBoxOrderBaseService {
    private final PmsService pmsService;
    private final RedissonClient redissonClient;
    private final RedisUtil redisUtil;
    private final RabbitTemplate rabbitTemplate;

    @Override
    public boolean cancelBlindBoxOrder(String orderSn) {
        LambdaQueryWrapper<BlindBoxOrderBaseEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BlindBoxOrderBaseEntity::getOrderSn, orderSn)
                .select();
        BlindBoxOrderBaseEntity one = this.getOne(lambdaQueryWrapper);
        if (one.getStatus() != OmsCommonConstant.WAITING_FOR_PAY) {
            return false;
        }
        //盲盒信息
        R<BlindBoxBaseEntity> blindBoxBaseInfo = pmsService.getBlindBoxBaseInfo(one.getBbId(), SecurityConstant.FROM_IN);
        BlindBoxBaseEntity blindBoxBaseEntity = OpsUtil.of(blindBoxBaseInfo)
                .assertDataNotNull(e -> new FastException("查询盲盒信息错误！"))
                .getData()
                .get();
        long begin = blindBoxBaseEntity.getStartTime().getTime();
        long end = blindBoxBaseEntity.getEndTime().getTime();
        long current = new Date().getTime();
        if (current < end) {
            PanicPurchaseProductRedisVO redisVO = (PanicPurchaseProductRedisVO) redisUtil.getHashValue(OmsCacheConstant.PRE_ON_SELL_DETAILS, String.format(OmsCacheConstant.BLIND_BOX_ON_SHELVE, one.getBbId(), begin, end));
            //回退信号量
            RSemaphore semaphore = redissonClient.getSemaphore(String.format(OmsCacheConstant.PRE_ON_SELL_STOCK, redisVO.getToken()));
            semaphore.release(one.getOrderNum());
            ClosePayInfoTO closePayInfoTO = new ClosePayInfoTO();
            closePayInfoTO.setOrderSn(orderSn);
            rabbitTemplate.convertAndSend(RabbitConstant.PAY_EXCHANGE, RabbitConstant.ALIPAY_CLOSE_ORDER_KEY, closePayInfoTO);
        }
        LambdaUpdateWrapper<BlindBoxOrderBaseEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(BlindBoxOrderBaseEntity::getId, one.getId())
                .set(BlindBoxOrderBaseEntity::getStatus, OmsCommonConstant.CANCEL_PAY);
        this.update(updateWrapper);
        return true;
    }

    @Override
    public boolean cancelBlindBoxNormalOrder(String orderSn) {
        LambdaQueryWrapper<BlindBoxOrderBaseEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BlindBoxOrderBaseEntity::getOrderSn, orderSn)
                .select();
        BlindBoxOrderBaseEntity one = this.getOne(lambdaQueryWrapper);
        if (one.getStatus() != OmsCommonConstant.WAITING_FOR_PAY) {
            return false;
        }
        LambdaUpdateWrapper<BlindBoxOrderBaseEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(BlindBoxOrderBaseEntity::getId, one.getId())
                .set(BlindBoxOrderBaseEntity::getStatus, OmsCommonConstant.CANCEL_PAY);
        this.update(updateWrapper);
        //解锁库存
        pmsService.unlockBlindBoxStock(one.getBbId(),SecurityConstant.FROM_IN);

        ClosePayInfoTO closePayInfoTO = new ClosePayInfoTO();
        closePayInfoTO.setOrderSn(orderSn);
        rabbitTemplate.convertAndSend(RabbitConstant.PAY_EXCHANGE, RabbitConstant.ALIPAY_CLOSE_ORDER_KEY, closePayInfoTO);
        return true;
    }
}